package com.example.lib_base

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.lib_base.entity.LocalEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import java.io.File

abstract class BaseViewModel<uiIntent : UIIntent> : ViewModel() {
    //存放管理意图的管道
    private val _uiIntent = Channel<UIIntent> { Channel.UNLIMITED }
    //Channel 是一种用于在协程之间安全传递数据的机制

    //Channel<UIIntent>这表示 _uiIntent 是一个 Channel，它用于发送和接收 UIIntent 类型的消息。
    // Channel 是一个泛型类，你需要指定它将传递的消息类型。

    //{ Channel.UNLIMITED }：这是 Channel 的构造函数的一个lambda表达式参数，用于配置通道的容量。
    // Channel.UNLIMITED 表示这个通道没有容量限制，即它可以存储任意数量的元素而不会阻塞发送者

    //可变的状态,用于更新UI
    private var _state = MutableStateFlow<UIState>(UIState.OnLoading)
    val state: StateFlow<UIState>
        get() = _state
    //get() = _state: 这是 state 属性的getter方法，它返回 _state 的当前值

    init {
        viewModelScope.launch {
            //receiveAsFlow()是一个扩展函数，用于将这些数据源转换为Kotlin的Flow类型
            _uiIntent.receiveAsFlow().collect {
                handleIntent(it)
            }
        }
    }

    //所有继承当前BaseViewModel的类,都需要实现该方法,来处理对应的意图
    //比如登录的Intent,需要处理登录的意图
    abstract fun handleIntent(it: UIIntent)

    //发送意图
    fun sendIntent(intent: UIIntent) {
        viewModelScope.launch {
            _uiIntent.send(intent)
        }
    }

    //fun httpRequest(request: Flow<Res<Any>>) {
    fun httpRequest(request: Flow<Res<Any>>, type: HttpType = HttpType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "error:${it.message}")
                }.collect {
                    if (it.code == 0) {
                        _state.value = UIState.OnSuccess(it.data,type)
                    } else {
                        _state.value = UIState.OnError(it.msg)
                    }
                }
        }
    }

    fun download(url: String, file: File) {
        viewModelScope.launch {
            DownloadUtil.download(url, file)
                .flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "downError:${it.message}")
                }.collect {
                    _state.value = it
                }
        }
    }

    fun scanFile(file: File) {
        viewModelScope.launch {
            try {
                //查找文件夹中所有的文件,形成一个list
                val files = file.listFiles()
                val list = mutableListOf<LocalEntity>()
                for (it in files) {
                    list.add(LocalEntity(it.name, it.absolutePath))
                }
                _state.value = UIState.OnSuccess(list)

            } catch (e: Exception) {
                _state.value = UIState.OnError(e.message.toString())
            }
        }
    }

    fun roomRequest(request: Flow<Any>, type: HttpType = HttpType.DEFAULT) {
    //fun roomRequest(request: Flow<Res<Any>>, type: HttpType = HttpType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch {
                    Log.e("TagA", "数据库错误:${it.message.toString()}")
                }.collect {
                    if (it != null) {
                        _state.value = UIState.OnSuccess(it, type)
                    } else {
                        _state.value = UIState.OnError("数据库操作错误")
                    }
                }
        }
    }

}